package Queue;

import java.util.Scanner;

public class CircleQueueDemo {

  public static void main(String[] args) {
    Circle queue = new Circle(4);
    char key = ' ';
    Scanner scanner = new Scanner(System.in);
    boolean loop = true;
    while (loop){
      System.out.println( "s(show):显示队列");
      System.out.println("e(exit):退出程序");
      System.out.println( "a(add):添加数据到队列");
      System.out.println("g(get):从队列取出数据");
      System.out.println("h(head):查看队列头的数据");
      key = scanner.next().charAt(0);
      switch (key) {
        case 's':
          queue.showQueue();
          break;
        case 'e':
          scanner.close();
          loop = false;
          break;
        case 'a':
          System.out.println("请输入一个数字");
          int value = scanner.nextInt();
          queue.addQueue(value);
          break;
        case 'g':
          try {
            int res = queue.getQueue();
            System.out.println("取出的数据" + res + " ");
          }catch (Exception e){
            e.printStackTrace();
          }
          break;
        case 'h':
          try {
            int head = queue.getHead();
            System.out.println(head);
          }catch (Exception e){
            e.printStackTrace();
          }
          break;
        default:
          break;
      }

    }
    System.out.println("程序退出");
  }
}

class Circle{
//  1.front变量的含义做一个调整:front就指向队列的第一个元素,也就是说arr[front]就是队列的第一个元素front的初始值=0
//  2. rear变量的含义做一个调整:rear指向队列的最后一个元素的后一个位置.因为希望空出一个空间做为约定.rear的初始值=0
//  3.当队列满时，条件是(rear + 1) %maxSize = front【满】
//  4.对队列为空的条件，rear == front空
//  5.当我们这样分析，队列中有效的数据的个数(rear+ maxSize - front)% maxSize // rear = 1 front =0

  private int maxSize; //表示数组的最大容量
  private int front; //队列头
  private int rear; //队列尾
  private int[] arr; //该数据用于存放数据,模拟队列

  //创建队列的构造器
  public Circle(int arrMaxSize) {
    maxSize = arrMaxSize;
    arr = new int[maxSize];
  }
  //判断队列是否满
  public boolean isFull(){
    return (rear + 1) % maxSize == front;
  }
  //判断队列是否为空
  public boolean isEmpty(){
    return rear == front;
  }
  //添加数据
  public void addQueue(int n){
    if (isFull()){
      System.out.println("队列满，不能添加数据");
      return;
    }
    //直接将数据加入
     arr[rear] = n;
    //将rear后移,这里必须考虑取模
     rear = (rear + 1)% maxSize;

  }
  //取出数据
  public int getQueue(){
    if (isEmpty()){
      throw new RuntimeException("队列为空，不能取数据");
    }
    //这里需要分析出front是指向队列的第一个元素
    // 1.先把front对应的值保留到一个临时变量
    // 2.将front后移，考虑取模
    // 3.将临时保存的变,返回
    int value = arr[front];
    front = (front + 1)% maxSize;
    return value;

  }
  //显示队列数据
  public void showQueue(){
    if (isEmpty()){
      System.out.println("队列为空，不能显示数据");
      return;
    }
    for (int i = front; i < front + size(); i++) {
      System.out.print(i % maxSize + " ");
      System.out.println(arr[i % maxSize]);
    }
  }
  //队列头部
  public int getHead(){
    if (isEmpty()){
      throw new RuntimeException("队列为空，不能取数据");
    }
    return arr[front];
  }

  //求出当前队列有效数据的个数
   public int size() {
    return (rear + maxSize - front) % maxSize;
  }

}
